import { EventData } from "./datas/EventData";
import { GameData } from "./datas/GameData";
import { GameBlock } from "./GameBlock";
import { GameCat } from "./GameCat";
import { GameConst } from "./GameConst";
import { CatDir, GameBlockData, GameCatData, GameCatPathData, GameState } from "./GameDefine";
import { MainConfig } from "./MainConfig";
import { AnimMgr } from "./managers/AnimMgr";
import { EventMgr } from "./managers/EventMgr";

/**
 * 游戏主界面
 * @Author: lzmxqh  
 * @Date: 2022-10-17 14:22:59  
 * @Last Modified by: lzmxqh
 * @Last Modified time: 2022-10-23 23:56:40
 */
export class GameScene extends Phaser.Scene {
    /**地图块地图 */
    private blockMap: GameBlock[][] = [];

    /**小猫 */
    private cat: GameCat;

    /**提示文本 */
    private tipText: Phaser.GameObjects.Text;

    /**游戏状态 */
    private state: GameState = GameState.PROGRESS;

    preload(): void {
        this.load.pack('pack1', './assets/pack.json', 'cat');
    }

    init(): void {

    }

    create(): void {
        const t = this;
        AnimMgr.getInst().loadAnims(t);

        t.initUI();
        t.initData();

        t.addListeners();
        t.events.on("destroy", t.removeListeners, t);
    }

    /**初始化UI */
    private initUI(): void {
        const t = this;
        t.createBg();
        t.createMap();
        t.createCat();
        t.createText();
    }

    /**创建背景 */
    private createBg(): void {
        const t = this;
        const leftX: number = +MainConfig.width / 2 - GameConst.BG_W / 2;
        const topY: number = +MainConfig.height / 2 - GameConst.BG_H / 2;

        const bg: Phaser.GameObjects.Graphics = t.add.graphics();
        bg.fillStyle(0xffffff);
        bg.fillRect(leftX, topY, GameConst.BG_W, GameConst.BG_H);
    }

    /**创建地图 */
    private createMap(): void {
        const t = this;
        const blockMap: GameBlock[][] = t.blockMap;
        for (let i = 0; i < GameConst.ROW; i++) {
            const blocks: GameBlock[] = [];
            for (let j = 0; j < GameConst.COL; j++) {
                const x: number = GameData.getBlockX(i, j);
                const y: number = GameData.getBlockY(i);
                const block: GameBlock = new GameBlock(t, x, y, {
                    row: i,
                    col: j,
                    isClick: false
                });
                blocks.push(block);
            }
            blockMap.push(blocks);
        }
    }

    /**创建小猫 */
    private createCat(): void {
        this.cat = new GameCat(this);
    }

    /**创建文本 */
    private createText(): void {
        const t = this;
        const centerX: number = +MainConfig.width / 2;
        const topY: number = +MainConfig.height / 2 - GameConst.BG_H / 2;

        // 提示文本
        const tipText: Phaser.GameObjects.Text = t.add.text(centerX, topY + 20, "点击小圆点，围住小猫", {
            fontFamily: "Monaco, Courier, monospace",
            fontSize: "48px",
            color: "#000000"
        });
        tipText.setOrigin(0.5, 0);
        t.tipText = tipText;

        const leftX: number = +MainConfig.width / 2 - GameConst.BG_W / 2;
        const bottomY: number = +MainConfig.height / 2 + GameConst.BG_H / 2;

        // 重置文本
        const resetText: Phaser.GameObjects.Text = t.add.text(leftX + 10, bottomY - 10, "重置", {
            fontFamily: "Monaco, Courier, monospace",
            fontSize: "48px",
            color: "#000000"
        }).setOrigin(0, 1);
        resetText.setInteractive().on("pointerup", t.onResetGame, t);
    }

    /**初始化数据 */
    private initData(): void {
        const t = this;
        t.state = GameState.PROGRESS;

        t.initCat();
        t.initBlockClicks();
    }

    /**初始化小猫 */
    private initCat(): void {
        this.cat.reset({
            row: Math.floor(GameConst.ROW / 2),
            col: Math.floor(GameConst.COL / 2),
            dir: CatDir.BOTTOM_LEFT
        });
    }

    /**初始化地图块点击状态 */
    private initBlockClicks(): void {
        // 重置地块
        const blockMap: GameBlock[][] = this.blockMap;
        blockMap.forEach(blocks => {
            blocks.forEach(block => {
                block.reset();
            })
        });

        // 随机地块
        const catData: GameCatData = this.cat.getCatData();
        for (let i = 0; i < GameConst.RANDOM_NUM; i++) {
            const row: number = Math.floor(Math.random() * GameConst.ROW);
            const col: number = Math.floor(Math.random() * GameConst.COL);

            if (row == catData.row && col == catData.col) {
                // 排除小猫所在位置
                continue;
            }
            blockMap[row][col].changeState(true);
        }
    }

    /**添加事件监听 */
    private addListeners(): void {
        const t = this;
        EventMgr.getInst().on(EventData.CLICK_BLOCK, t.clickBlock, t);
        EventMgr.getInst().on(EventData.MOVE_END, t.moveEnd, t);
    }

    /**移除事件监听 */
    private removeListeners(): void {
        const t = this;
        EventMgr.getInst().off(EventData.CLICK_BLOCK, t.clickBlock, t);
        EventMgr.getInst().off(EventData.MOVE_END, t.moveEnd, t);
    }

    /**刷新提示文本 */
    private updateTipText(text: string): void {
        this.tipText.setText(text);
    }

    update(time: number, delta: number): void {

    }

    /**重置游戏 */
    private onResetGame(): void {
        const t = this;
        console.log("重置");

        t.initData();
        t.updateTipText("点击小圆点，围住小猫");
    }

    /**点击地块 */
    private clickBlock(blockData?: GameBlockData): void {
        const t = this;
        if (t.state == GameState.END) {
            t.onResetGame();
            return;
        }

        const cat: GameCat = t.cat;
        const catData: GameCatData = cat.getCatData();
        if (GameData.isFail(catData)) {
            t.state = GameState.END;
            t.updateTipText("猫已经跑到地图边缘了，你输了");
            return;
        }

        if (!blockData) {
            t.updateTipText("点击位置已经是墙了，禁止点击");
            return;
        }
        if (blockData.row == catData.row && blockData.col == catData.col) {
            t.updateTipText("点击位置是猫当前位置，禁止点击");
            return;
        }
        t.updateTipText("点击位置" + "(行: " + (blockData.row + 1) + ",列: " + (blockData.col + 1) + ")");

        // 改变地块状态
        t.blockMap[blockData.row][blockData.col].changeState(true);

        const isWin: boolean = GameData.isWin(t.blockMap, catData);
        if (isWin) {
            t.state = GameState.END;
            t.updateTipText("猫已经无路可走，你赢了");
            return;
        }

        // 小猫执行下一步，获取小猫行走路径
        let pathData: GameCatPathData = { curData: catData, distance: 0 };
        pathData = GameData.getCatNextPos(t.blockMap, pathData, [pathData], [catData]);

        if (pathData) {
            const nextData: GameCatData = GameData.getFirstDataByPath(pathData);
            t.cat.gotoBlock(nextData.row, nextData.col);
        }
    }

    /**小猫移动结束 */
    private moveEnd(): void {
        const t = this;
        const catData: GameCatData = t.cat.getCatData();
        if (!GameData.isFail(catData)) {
            return;
        }
        t.state = GameState.END;
        t.updateTipText("猫已经跑到地图边缘了，你输了");

        // 小猫从该方向跑路
        const tarCatData: GameCatData = GameData.getCatRunPos(catData);
        t.cat.gotoBlock(tarCatData.row, tarCatData.col, true, tarCatData.dir);
    }
}
